feat: production-grade escrow lifecycle hardening#4
Merged
natalya-bbr merged 18 commits intomainfrom Dec 11, 2025
Merged
Conversation
Add comprehensive tests for SafeBaseEscrowV1 covering: - Proxy initialization - Escrow creation with validation - State transitions - Pause/unpause functionality - Upgrade authorization
…d Treasury - RulesEngineV1: test rule creation, validation, and conditional logic - RegistryV1: test escrow indexing, pagination, and party queries - ExecutorV1: test automation, deadline checks, and access control - Treasury: test multi-sig withdrawal flow, admin management, and ERC20 support - Update foundry.toml with gas reports and fuzz configuration
- Remove incomplete workflow files (deps.yml, slither-analysis.yml) - Update CI to run on both main and develop branches - Add gas snapshot tracking with 5% tolerance - Add contract size reporting in build step - Add coverage report with lcov format - Add Codecov integration for coverage tracking
- Change ETH transfer from transfer() to call{value}()
- transfer() has 2300 gas limit which fails with UUPS proxies
- call() forwards all available gas allowing proxy fallback to execute
- Add error handling for failed transfers
- Fixes 17 failing tests in SafeBaseEscrowV1Test
Resolves OutOfGas errors when funding escrow with ETH to Treasury proxy.
- Add treasury.executeWithdrawal() after approveWithdrawal() - Ensures funds are immediately transferred to recipient - releaseToSeller now completes full withdrawal flow - refundToBuyer now completes full withdrawal flow - Fixes 4 failing balance assertion tests This completes the withdrawal process instead of just approving it, since SafeBaseEscrow has both admin and executor roles in Treasury.
- Add conditional check for .gas-snapshot file existence - Create snapshot on first run instead of checking - Check snapshot with 5% tolerance on subsequent runs - Prevents CI failure when snapshot file doesn't exist Fixes "No such file or directory" error in GitHub Actions.
- Add UpgradeContract.s.sol for upgrading any UUPS contract - Add GitHub Actions workflow for manual contract upgrades - Supports all contracts: Treasury, SafeBaseEscrow, RulesEngine, etc. - Choose network (sepolia/mainnet) and contract via UI - Includes dry run simulation before actual upgrade - Auto-verifies new implementation on Basescan Usage: GitHub Actions -> Upgrade Contract -> Run workflow
Base Mainnet (8453): - Old: 0x4b015dF938d053388796078FA3F5145C550C4EE8 - New: 0x57741EE5bAc991D43Cf71207781fCB0eE4b9e9a8 - Verified: https://basescan.org/address/0x57741ee5bac991d43cf71207781fcb0ee4b9e9a8 Base Sepolia (84532): - Old: 0x9b0C3872234e403aa62F7315122019c22D9e4F11 - New: 0xF2a7fbffD5760721C99104A7C1f500797F3D1314 - Verified: https://sepolia.basescan.org/address/0xf2a7fbffd5760721c99104a7c1f500797f3d1314 Changes in upgraded implementation: - Fixed OutOfGas issue with ETH transfers to Treasury proxy - Added executeWithdrawal calls for immediate fund transfers - All 85 tests passing
In OZ v4.9.6, __Ownable_init() takes no parameters. Use _transferOwnership() to set custom owner after initialization. Fixes initialization in: - SafeBaseEscrowV1 - RulesEngineV1
Added comprehensive tests for mediator-driven resolution of disputed escrows: - testDisputedToReleased: mediator releases funds after dispute - testDisputedToReleasedRequiresMediator: buyer cannot release from Disputed - testMultipleDisputeAttempts: prevents double-dispute - testReleaseAfterDeadlineWithApproval: approval works post-deadline - testCannotReleaseFromCancelledState: terminal state enforcement - testCannotRefundFromCancelledState: terminal state enforcement Covers edge cases identified in lifecycle hardening audit.
Created SafeBaseEscrowRulesIntegration.t.sol covering: - Release with rules-based approval logic - Refund with deadline-based rules - Mediator override capabilities - Disputed state resolution with rules - Backward compatibility (ruleSetId = 0) Validates complete integration between SafeBaseEscrowV1 and RulesEngineV1 across all state transitions.
Comprehensive documentation for SafeBase escrow state machine: - 6 states with complete transition diagram - Authorization matrix for each role - RulesEngine integration patterns - Invariants (state, financial, temporal) - Edge cases and race conditions - Security model and attack vectors - Integration examples and upgrade guide Serves as reference for developers integrating with SafeBase and auditors reviewing lifecycle logic.
OpenZeppelin v5.x requires initialOwner parameter in __Ownable_init(). Updated initialization to use __Ownable_init(_owner) instead of parameterless init followed by transferOwnership. Fixes compilation errors in SafeBaseEscrowV1 and RulesEngineV1.
Moved approveBuyer() call before disputeEscrow() since approvals are only allowed in Funded state. Test now correctly verifies that buyer cannot release from Disputed state even with prior approval.
Added explicit check that when escrow.state == Disputed, only the mediator can call releaseToSeller() or refundToBuyer(). This prevents buyers/sellers from bypassing dispute resolution using prior approvals. Critical invariant: Disputed escrows require mediator intervention.
Update implementation addresses for SafeBaseEscrow and RulesEngine following successful UUPS upgrades on Base Sepolia and Mainnet. Base Sepolia (84532): - SafeBaseEscrow: 0x682026827839A367252Ec80a0bbaaA47AFA3d870 - RulesEngine: 0xFA439194fe9B624AD51f7ecccf9FbcdB4350Bc70 Base Mainnet (8453): - SafeBaseEscrow: 0xA1e13a0E7E54bC71ee4173D74773b455A86816aB - RulesEngine: 0xB49e7b4cCB76B3aE9439798eb980434CBCF8c428 All contracts verified on Basescan.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements: Escrow lifecycle hardening to production-grade standards with RulesEngine integration, comprehensive testing, and successful Base deployment.
Changes
Core Features
ruleSetId